Sooooo nothing with BEC zones has been promising so far. Let’s try something else. Let’s switch to VRI data and see if amount of mature/old growth forest is related to amount of squirrel in the diet, since squirrels like old forests.

# Load some libraries.
library(tidyverse)
library(landscapemetrics)
library(raster)
library(sf)
library(AICcmodavg)
library(MuMIn)

# Bring in diet data.
df <- read_csv('../data/interim/camera_corrected.csv', guess_max=7000)
# I had some trouble with readr so I increased the number of rows used to guess.

source('../src/prey_attributes.R')

head(items)

# Calculate proportion of diet made up of squirrel at each site.
sq.mass <- items %>% mutate(mass=as.numeric(mass)) %>% 
  group_by(site) %>% 
  mutate(total=sum(mass)) %>% 
  filter(genus == 'Tamiasciurus') %>% 
  mutate(amount.sq=sum(mass), prop.sq=amount.sq/total) %>% 
  dplyr::select(site, prop.sq) %>% distinct()

sq.mass

That’s remarkably consistent.

The next step is to get the amount of mature forest for each of these sites. Unfortunately, the VRI data for Turbid Creek is useless so that drops me down to five sites. But I can pull in the VRI for the others…

# Import transition zone shapefile.
vri <- st_read('../data/external/VRI_camera-sites_2019.shp')
Reading layer `VRI_camera-sites_2019' from data source `C:\Users\gwync\sfuvault\productivity-occupancy\data\external\VRI_camera-sites_2019.shp' using driver `ESRI Shapefile'
Simple feature collection with 13321 features and 188 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: 413289.1 ymin: 5428268 xmax: 645675.7 ymax: 5589928
projected CRS:  WGS 84 / UTM zone 10N

Then I need to rasterize it. Which means first I need to break it down into classes so I can assign a raster value. Unfortunately there’s no single field in the VRI data that works for classification. I can break this into:

# Assign to classes.
# Regen/young/mature/old ages come from Zharikov et al. 2007
vri.class <- vri %>% mutate(hab.class=case_when(
  # Non-vegetated and water
  BCLCS_LV_1 == 'N' & BCLCS_LV_2 == 'W' ~ 1, 
  # Non-vegetated and not water
  BCLCS_LV_1 == 'N' & BCLCS_LV_2 != 'W' ~ 2, 
  # Vegetated and not trees
  BCLCS_LV_1 == 'V' & BCLCS_LV_2 == 'N' ~ 3,
  # Vegetated and mixed or deciduous trees
  BCLCS_LV_1 == 'V' & BCLCS_LV_4 %in% c('TB', 'TM') ~ 4,
  # Vegetated and coniferous trees
  BCLCS_LV_4 == 'TC' & PROJ_AGE_1 < 20 ~ 5,
  BCLCS_LV_4 == 'TC' & PROJ_AGE_1 >= 20 & PROJ_AGE_1 < 60 ~ 6,
  BCLCS_LV_4 == 'TC' & PROJ_AGE_1 >= 60 & PROJ_AGE_1 < 140 ~ 7,
  BCLCS_LV_4 == 'TC' & PROJ_AGE_1 >= 140 ~ 8,
  TRUE ~ 0
))

# See how it turned out.
vri.class %>% group_by(hab.class) %>% summarise(n())
Simple feature collection with 9 features and 2 fields
geometry type:  MULTIPOLYGON
dimension:      XY
bbox:           xmin: 413289.1 ymin: 5428268 xmax: 645675.7 ymax: 5589928
projected CRS:  WGS 84 / UTM zone 10N

A little investigating shows that the 4 polygons classed as 0 are unclassified in the VRI or conifer polygons with unknown ages, so that seems fine.

# Set raster extent based on tz shapefile.
ext <- extent(vri)

# Make an empty raster to populate with values.
r <- raster(ext, res=c(100, 100))

# Populate BEC polygon data onto empty raster grid.
r.vri <- rasterize(vri.class, r, 'hab.class')

# Create labels for raster.
vri.levels <- data.frame(ID=0:8, class.name=c('undefined', 'water', 'land', 'unforested', 'deciduous', 'regen', 'young', 'mature', 'old'))

# Add them to the raster.
levels(r.vri) <- vri.levels

# Save the raster image.
writeRaster(r.vri, '../data/interim/vri_camera-sites_2019.tif', format='GTiff')

If picking up later, load up the raster and keep going.

# Import the raster.
r.vri <- raster('../data/interim/vri_camera-sites_2019.tif')

# Import nests and calculate centroids.
sites <- read_csv('../data/processed/the_big_list_of_nests.csv') %>% 
  group_by(name) %>% 
  mutate_at(c('lat', 'lon'), mean) %>% 
  mutate_at(vars(starts_with('status')), max) %>% 
  mutate_at(c('telemetry', 'cameras', 'remains'), max) %>% 
  dplyr::select(-nest, -NOTES) %>% 
  distinct() %>% 
  filter(cameras > 0)

# Drop TCR, ungroup.
sites <- sites %>% filter(site != 'TCR') %>% 
  ungroup()

# Make site table a spatial object and make it UTMs.
sites.sf <- ungroup(sites) %>% st_as_sf(coords=c('lon', 'lat')) %>%
  st_set_crs('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs') %>%
  st_transform("+proj=utm +zone=10 +datum=WGS84 +units=m +no_defs")

# Convert approximate homerange area in ha to radius in m
a.hr.ha <- 3700
r.hr.m <- sqrt(a.hr.ha*10000/pi)

# Calculate area per class per site.
class.area <- sample_lsm(r.vri, y=sites.sf, size=r.hr.m, what='lsm_c_ca', 
           shape='circle') %>% 
  # Amend class number with habitat class name.
  left_join(data.frame(levels(r.vri)), by=c('class'='ID')) %>% 
# Reorganize by site.  
  pivot_wider(id_cols=plot_id, names_from=category, values_from=value, 
              values_fill=list(value=0))

# Amend with site names.
class.area <- dplyr::select(sites, site) %>% rownames_to_column() %>% 
  mutate(rowname=as.integer(rowname)) %>% 
  right_join(class.area, by=c('rowname'='plot_id'))

class.area

Ok that looks good so far. Obviously Ruby Lake is the one with all the water. Otherwise, there seems to be a fair bit of variability regarding the different cover types.

I have two age classes that might be relevant to squirrels: mature and old. So amount of squirrel might be related to mature or old, or it might be related to mature and old. (Or, more likely, it is related to neither.)

# Join VRi and diet data together.
sq.vri <- sq.mass %>% filter(site != 'TCR') %>% left_join(class.area)

# Sum mature and old forest classes
sq.vri <- sq.vri %>% mutate(older=sum(mature, old))

sq.vri

# Plot it.
ggplot(sq.vri, aes(x=older, y=prop.sq, label=site)) +
  geom_point() +
  geom_text(hjust='inward', nudge_y = 0.5) +
  geom_smooth(method='lm', se=FALSE, color='black', linetype='dashed') +
  theme_classic()

Shocking! There’s actually kind of almost a little bit of a pattern. So here are my models:

# Proportion of squirrel biomass is function of amount of mature forest.
sq.x.mature <- lm(prop.sq ~ mature, data=sq.vri)

# Proportion of squirrel biomass is function of amount of old forest.
sq.x.old <- lm(prop.sq ~ old, data=sq.vri)

# Proportion of squirrel biomass if function of total older forest.
sq.x.older <- lm(prop.sq ~ older, data=sq.vri)

# Do the AIC thing.
models <- list(sq.x.mature, sq.x.old, sq.x.older)
modnames <- c('mature', 'old', 'older')

aictab(models, modnames=modnames)

Model selection based on AICc:

       K  AICc Delta_AICc AICcWt Cum.Wt   LL
older  3 17.40       0.00   0.62   0.62 6.30
old    3 19.00       1.61   0.28   0.89 5.50
mature 3 20.93       3.53   0.11   1.00 4.54
# And the R2 thing.
summary(sq.x.mature)$r.squared
[1] 0.1190584
summary(sq.x.old)$r.squared
[1] 0.4006557
summary(sq.x.older)$r.squared
[1] 0.5652464

Which does not look promising. But the other option is to look at core area, assuming squirrels avoid edge. The problem here is that I should combine both old and mature forest into a single category, so that edge between them doesn’t count, and that probably requires remaking my raster.

LS0tDQp0aXRsZTogIkVkZ2Ugc3BlY2llcyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSkNCmBgYA0KDQpTb29vb28gbm90aGluZyB3aXRoIEJFQyB6b25lcyBoYXMgYmVlbiBwcm9taXNpbmcgc28gZmFyLiBMZXQncyB0cnkgc29tZXRoaW5nIGVsc2UuIExldCdzIHN3aXRjaCB0byBWUkkgZGF0YSBhbmQgc2VlIGlmIGFtb3VudCBvZiBtYXR1cmUvb2xkIGdyb3d0aCBmb3Jlc3QgaXMgcmVsYXRlZCB0byBhbW91bnQgb2Ygc3F1aXJyZWwgaW4gdGhlIGRpZXQsIHNpbmNlIHNxdWlycmVscyBsaWtlIG9sZCBmb3Jlc3RzLg0KDQpgYGB7cn0NCiMgTG9hZCBzb21lIGxpYnJhcmllcy4NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShsYW5kc2NhcGVtZXRyaWNzKQ0KbGlicmFyeShyYXN0ZXIpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShBSUNjbW9kYXZnKQ0KbGlicmFyeShNdU1JbikNCg0KIyBCcmluZyBpbiBkaWV0IGRhdGEuDQpkZiA8LSByZWFkX2NzdignLi4vZGF0YS9pbnRlcmltL2NhbWVyYV9jb3JyZWN0ZWQuY3N2JywgZ3Vlc3NfbWF4PTcwMDApDQojIEkgaGFkIHNvbWUgdHJvdWJsZSB3aXRoIHJlYWRyIHNvIEkgaW5jcmVhc2VkIHRoZSBudW1iZXIgb2Ygcm93cyB1c2VkIHRvIGd1ZXNzLg0KDQpzb3VyY2UoJy4uL3NyYy9wcmV5X2F0dHJpYnV0ZXMuUicpDQoNCmhlYWQoaXRlbXMpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gb2YgZGlldCBtYWRlIHVwIG9mIHNxdWlycmVsIGF0IGVhY2ggc2l0ZS4NCnNxLm1hc3MgPC0gaXRlbXMgJT4lIG11dGF0ZShtYXNzPWFzLm51bWVyaWMobWFzcykpICU+JSANCiAgZ3JvdXBfYnkoc2l0ZSkgJT4lIA0KICBtdXRhdGUodG90YWw9c3VtKG1hc3MpKSAlPiUgDQogIGZpbHRlcihnZW51cyA9PSAnVGFtaWFzY2l1cnVzJykgJT4lIA0KICBtdXRhdGUoYW1vdW50LnNxPXN1bShtYXNzKSwgcHJvcC5zcT1hbW91bnQuc3EvdG90YWwpICU+JSANCiAgZHBseXI6OnNlbGVjdChzaXRlLCBwcm9wLnNxKSAlPiUgZGlzdGluY3QoKQ0KDQpzcS5tYXNzDQpgYGANCg0KVGhhdCdzIHJlbWFya2FibHkgY29uc2lzdGVudC4NCg0KVGhlIG5leHQgc3RlcCBpcyB0byBnZXQgdGhlIGFtb3VudCBvZiBtYXR1cmUgZm9yZXN0IGZvciBlYWNoIG9mIHRoZXNlIHNpdGVzLiBVbmZvcnR1bmF0ZWx5LCB0aGUgVlJJIGRhdGEgZm9yIFR1cmJpZCBDcmVlayBpcyB1c2VsZXNzIHNvIHRoYXQgZHJvcHMgbWUgZG93biB0byBmaXZlIHNpdGVzLiBCdXQgSSBjYW4gcHVsbCBpbiB0aGUgVlJJIGZvciB0aGUgb3RoZXJzLi4uDQoNCmBgYHtyfQ0KIyBJbXBvcnQgdHJhbnNpdGlvbiB6b25lIHNoYXBlZmlsZS4NCnZyaSA8LSBzdF9yZWFkKCcuLi9kYXRhL2V4dGVybmFsL1ZSSV9jYW1lcmEtc2l0ZXNfMjAxOS5zaHAnKQ0KYGBgDQoNClRoZW4gSSBuZWVkIHRvIHJhc3Rlcml6ZSBpdC4gV2hpY2ggbWVhbnMgZmlyc3QgSSBuZWVkIHRvIGJyZWFrIGl0IGRvd24gaW50byBjbGFzc2VzIHNvIEkgY2FuIGFzc2lnbiBhIHJhc3RlciB2YWx1ZS4gVW5mb3J0dW5hdGVseSB0aGVyZSdzIG5vIHNpbmdsZSBmaWVsZCBpbiB0aGUgVlJJIGRhdGEgdGhhdCB3b3JrcyBmb3IgY2xhc3NpZmljYXRpb24uIEkgY2FuIGJyZWFrIHRoaXMgaW50bzoNCg0KKiBXYXRlciAoMSkNCiogTGFuZCAodW52ZWdldGF0ZWQpICgyKQ0KKiBWZWdldGF0ZWQgKG5vdCBmb3Jlc3QpICgzKQ0KKiBEZWNpZHVvdXMgKDQpDQoqIENvbmlmZXJvdXMgKHJlZ2VuLCB5b3VuZywgbWVkaXVtLCBhbmQgb2xkKSAoNSwgNiwgNywgOCkNCg0KYGBge3J9DQojIEFzc2lnbiB0byBjbGFzc2VzLg0KIyBSZWdlbi95b3VuZy9tYXR1cmUvb2xkIGFnZXMgY29tZSBmcm9tIFpoYXJpa292IGV0IGFsLiAyMDA3DQp2cmkuY2xhc3MgPC0gdnJpICU+JSBtdXRhdGUoaGFiLmNsYXNzPWNhc2Vfd2hlbigNCiAgIyBOb24tdmVnZXRhdGVkIGFuZCB3YXRlcg0KICBCQ0xDU19MVl8xID09ICdOJyAmIEJDTENTX0xWXzIgPT0gJ1cnIH4gMSwgDQogICMgTm9uLXZlZ2V0YXRlZCBhbmQgbm90IHdhdGVyDQogIEJDTENTX0xWXzEgPT0gJ04nICYgQkNMQ1NfTFZfMiAhPSAnVycgfiAyLCANCiAgIyBWZWdldGF0ZWQgYW5kIG5vdCB0cmVlcw0KICBCQ0xDU19MVl8xID09ICdWJyAmIEJDTENTX0xWXzIgPT0gJ04nIH4gMywNCiAgIyBWZWdldGF0ZWQgYW5kIG1peGVkIG9yIGRlY2lkdW91cyB0cmVlcw0KICBCQ0xDU19MVl8xID09ICdWJyAmIEJDTENTX0xWXzQgJWluJSBjKCdUQicsICdUTScpIH4gNCwNCiAgIyBWZWdldGF0ZWQgYW5kIGNvbmlmZXJvdXMgdHJlZXMNCiAgQkNMQ1NfTFZfNCA9PSAnVEMnICYgUFJPSl9BR0VfMSA8IDIwIH4gNSwNCiAgQkNMQ1NfTFZfNCA9PSAnVEMnICYgUFJPSl9BR0VfMSA+PSAyMCAmIFBST0pfQUdFXzEgPCA2MCB+IDYsDQogIEJDTENTX0xWXzQgPT0gJ1RDJyAmIFBST0pfQUdFXzEgPj0gNjAgJiBQUk9KX0FHRV8xIDwgMTQwIH4gNywNCiAgQkNMQ1NfTFZfNCA9PSAnVEMnICYgUFJPSl9BR0VfMSA+PSAxNDAgfiA4LA0KICBUUlVFIH4gMA0KKSkNCg0KIyBTZWUgaG93IGl0IHR1cm5lZCBvdXQuDQp2cmkuY2xhc3MgJT4lIGdyb3VwX2J5KGhhYi5jbGFzcykgJT4lIHN1bW1hcmlzZShuKCkpDQpgYGANCg0KQSBsaXR0bGUgaW52ZXN0aWdhdGluZyBzaG93cyB0aGF0IHRoZSA0IHBvbHlnb25zIGNsYXNzZWQgYXMgMCBhcmUgdW5jbGFzc2lmaWVkIGluIHRoZSBWUkkgb3IgY29uaWZlciBwb2x5Z29ucyB3aXRoIHVua25vd24gYWdlcywgc28gdGhhdCBzZWVtcyBmaW5lLiANCg0KYGBge3IgZXZhbD1GQUxTRX0NCiMgU2V0IHJhc3RlciBleHRlbnQgYmFzZWQgb24gdHogc2hhcGVmaWxlLg0KZXh0IDwtIGV4dGVudCh2cmkpDQoNCiMgTWFrZSBhbiBlbXB0eSByYXN0ZXIgdG8gcG9wdWxhdGUgd2l0aCB2YWx1ZXMuDQpyIDwtIHJhc3RlcihleHQsIHJlcz1jKDEwMCwgMTAwKSkNCg0KIyBQb3B1bGF0ZSBCRUMgcG9seWdvbiBkYXRhIG9udG8gZW1wdHkgcmFzdGVyIGdyaWQuDQpyLnZyaSA8LSByYXN0ZXJpemUodnJpLmNsYXNzLCByLCAnaGFiLmNsYXNzJykNCg0KIyBDcmVhdGUgbGFiZWxzIGZvciByYXN0ZXIuDQp2cmkubGV2ZWxzIDwtIGRhdGEuZnJhbWUoSUQ9MDo4LCBjbGFzcy5uYW1lPWMoJ3VuZGVmaW5lZCcsICd3YXRlcicsICdsYW5kJywgJ3VuZm9yZXN0ZWQnLCAnZGVjaWR1b3VzJywgJ3JlZ2VuJywgJ3lvdW5nJywgJ21hdHVyZScsICdvbGQnKSkNCg0KIyBBZGQgdGhlbSB0byB0aGUgcmFzdGVyLg0KbGV2ZWxzKHIudnJpKSA8LSB2cmkubGV2ZWxzDQoNCiMgU2F2ZSB0aGUgcmFzdGVyIGltYWdlLg0Kd3JpdGVSYXN0ZXIoci52cmksICcuLi9kYXRhL2ludGVyaW0vdnJpX2NhbWVyYS1zaXRlc18yMDE5LnRpZicsIGZvcm1hdD0nR1RpZmYnKQ0KYGBgDQoNCklmIHBpY2tpbmcgdXAgbGF0ZXIsIGxvYWQgdXAgdGhlIHJhc3RlciBhbmQga2VlcCBnb2luZy4NCg0KYGBge3J9DQojIEltcG9ydCB0aGUgcmFzdGVyLg0Kci52cmkgPC0gcmFzdGVyKCcuLi9kYXRhL2ludGVyaW0vdnJpX2NhbWVyYS1zaXRlc18yMDE5LnRpZicpDQoNCiMgSW1wb3J0IG5lc3RzIGFuZCBjYWxjdWxhdGUgY2VudHJvaWRzLg0Kc2l0ZXMgPC0gcmVhZF9jc3YoJy4uL2RhdGEvcHJvY2Vzc2VkL3RoZV9iaWdfbGlzdF9vZl9uZXN0cy5jc3YnKSAlPiUgDQogIGdyb3VwX2J5KG5hbWUpICU+JSANCiAgbXV0YXRlX2F0KGMoJ2xhdCcsICdsb24nKSwgbWVhbikgJT4lIA0KICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgnc3RhdHVzJykpLCBtYXgpICU+JSANCiAgbXV0YXRlX2F0KGMoJ3RlbGVtZXRyeScsICdjYW1lcmFzJywgJ3JlbWFpbnMnKSwgbWF4KSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoLW5lc3QsIC1OT1RFUykgJT4lIA0KICBkaXN0aW5jdCgpICU+JSANCiAgZmlsdGVyKGNhbWVyYXMgPiAwKQ0KDQojIERyb3AgVENSLCB1bmdyb3VwLg0Kc2l0ZXMgPC0gc2l0ZXMgJT4lIGZpbHRlcihzaXRlICE9ICdUQ1InKSAlPiUgDQogIHVuZ3JvdXAoKQ0KDQojIE1ha2Ugc2l0ZSB0YWJsZSBhIHNwYXRpYWwgb2JqZWN0IGFuZCBtYWtlIGl0IFVUTXMuDQpzaXRlcy5zZiA8LSB1bmdyb3VwKHNpdGVzKSAlPiUgc3RfYXNfc2YoY29vcmRzPWMoJ2xvbicsICdsYXQnKSkgJT4lDQogIHN0X3NldF9jcnMoJytwcm9qPWxvbmdsYXQgK2VsbHBzPVdHUzg0ICtkYXR1bT1XR1M4NCArbm9fZGVmcycpICU+JQ0KICBzdF90cmFuc2Zvcm0oIitwcm9qPXV0bSArem9uZT0xMCArZGF0dW09V0dTODQgK3VuaXRzPW0gK25vX2RlZnMiKQ0KDQojIENvbnZlcnQgYXBwcm94aW1hdGUgaG9tZXJhbmdlIGFyZWEgaW4gaGEgdG8gcmFkaXVzIGluIG0NCmEuaHIuaGEgPC0gMzcwMA0Kci5oci5tIDwtIHNxcnQoYS5oci5oYSoxMDAwMC9waSkNCg0KIyBDYWxjdWxhdGUgYXJlYSBwZXIgY2xhc3MgcGVyIHNpdGUuDQpjbGFzcy5hcmVhIDwtIHNhbXBsZV9sc20oci52cmksIHk9c2l0ZXMuc2YsIHNpemU9ci5oci5tLCB3aGF0PSdsc21fY19jYScsIA0KICAgICAgICAgICBzaGFwZT0nY2lyY2xlJykgJT4lIA0KICAjIEFtZW5kIGNsYXNzIG51bWJlciB3aXRoIGhhYml0YXQgY2xhc3MgbmFtZS4NCiAgbGVmdF9qb2luKGRhdGEuZnJhbWUobGV2ZWxzKHIudnJpKSksIGJ5PWMoJ2NsYXNzJz0nSUQnKSkgJT4lIA0KIyBSZW9yZ2FuaXplIGJ5IHNpdGUuICANCiAgcGl2b3Rfd2lkZXIoaWRfY29scz1wbG90X2lkLCBuYW1lc19mcm9tPWNhdGVnb3J5LCB2YWx1ZXNfZnJvbT12YWx1ZSwgDQogICAgICAgICAgICAgIHZhbHVlc19maWxsPWxpc3QodmFsdWU9MCkpDQoNCiMgQW1lbmQgd2l0aCBzaXRlIG5hbWVzLg0KY2xhc3MuYXJlYSA8LSBkcGx5cjo6c2VsZWN0KHNpdGVzLCBzaXRlKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCkgJT4lIA0KICBtdXRhdGUocm93bmFtZT1hcy5pbnRlZ2VyKHJvd25hbWUpKSAlPiUgDQogIHJpZ2h0X2pvaW4oY2xhc3MuYXJlYSwgYnk9Yygncm93bmFtZSc9J3Bsb3RfaWQnKSkNCg0KY2xhc3MuYXJlYQ0KYGBgDQoNCk9rIHRoYXQgbG9va3MgZ29vZCBzbyBmYXIuIE9idmlvdXNseSBSdWJ5IExha2UgaXMgdGhlIG9uZSB3aXRoIGFsbCB0aGUgd2F0ZXIuIE90aGVyd2lzZSwgdGhlcmUgc2VlbXMgdG8gYmUgYSBmYWlyIGJpdCBvZiB2YXJpYWJpbGl0eSByZWdhcmRpbmcgdGhlIGRpZmZlcmVudCBjb3ZlciB0eXBlcy4NCg0KSSBoYXZlIHR3byBhZ2UgY2xhc3NlcyB0aGF0IG1pZ2h0IGJlIHJlbGV2YW50IHRvIHNxdWlycmVsczogbWF0dXJlIGFuZCBvbGQuIFNvIGFtb3VudCBvZiBzcXVpcnJlbCBtaWdodCBiZSByZWxhdGVkIHRvIG1hdHVyZSAqb3IqIG9sZCwgb3IgaXQgbWlnaHQgYmUgcmVsYXRlZCB0byBtYXR1cmUgKmFuZCogb2xkLiAoT3IsIG1vcmUgbGlrZWx5LCBpdCBpcyByZWxhdGVkIHRvIG5laXRoZXIuKQ0KDQpgYGB7cn0NCiMgSm9pbiBWUmkgYW5kIGRpZXQgZGF0YSB0b2dldGhlci4NCnNxLnZyaSA8LSBzcS5tYXNzICU+JSBmaWx0ZXIoc2l0ZSAhPSAnVENSJykgJT4lIGxlZnRfam9pbihjbGFzcy5hcmVhKQ0KDQojIFN1bSBtYXR1cmUgYW5kIG9sZCBmb3Jlc3QgY2xhc3Nlcw0Kc3EudnJpIDwtIHNxLnZyaSAlPiUgbXV0YXRlKG9sZGVyPXN1bShtYXR1cmUsIG9sZCkpDQoNCnNxLnZyaQ0KDQojIFBsb3QgaXQuDQpnZ3Bsb3Qoc3EudnJpLCBhZXMoeD1vbGRlciwgeT1wcm9wLnNxLCBsYWJlbD1zaXRlKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX3RleHQoaGp1c3Q9J2lud2FyZCcsIG51ZGdlX3kgPSAwLjUpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSdsbScsIHNlPUZBTFNFLCBjb2xvcj0nYmxhY2snLCBsaW5ldHlwZT0nZGFzaGVkJykgKw0KICB0aGVtZV9jbGFzc2ljKCkNCmBgYA0KDQpTaG9ja2luZyEgVGhlcmUncyBhY3R1YWxseSBraW5kIG9mIGFsbW9zdCBhIGxpdHRsZSBiaXQgb2YgYSBwYXR0ZXJuLiBTbyBoZXJlIGFyZSBteSBtb2RlbHM6DQoNCmBgYHtyfQ0KIyBQcm9wb3J0aW9uIG9mIHNxdWlycmVsIGJpb21hc3MgaXMgZnVuY3Rpb24gb2YgYW1vdW50IG9mIG1hdHVyZSBmb3Jlc3QuDQpzcS54Lm1hdHVyZSA8LSBsbShwcm9wLnNxIH4gbWF0dXJlLCBkYXRhPXNxLnZyaSkNCg0KIyBQcm9wb3J0aW9uIG9mIHNxdWlycmVsIGJpb21hc3MgaXMgZnVuY3Rpb24gb2YgYW1vdW50IG9mIG9sZCBmb3Jlc3QuDQpzcS54Lm9sZCA8LSBsbShwcm9wLnNxIH4gb2xkLCBkYXRhPXNxLnZyaSkNCg0KIyBQcm9wb3J0aW9uIG9mIHNxdWlycmVsIGJpb21hc3MgaWYgZnVuY3Rpb24gb2YgdG90YWwgb2xkZXIgZm9yZXN0Lg0Kc3EueC5vbGRlciA8LSBsbShwcm9wLnNxIH4gb2xkZXIsIGRhdGE9c3EudnJpKQ0KDQojIERvIHRoZSBBSUMgdGhpbmcuDQptb2RlbHMgPC0gbGlzdChzcS54Lm1hdHVyZSwgc3EueC5vbGQsIHNxLngub2xkZXIpDQptb2RuYW1lcyA8LSBjKCdtYXR1cmUnLCAnb2xkJywgJ29sZGVyJykNCg0KYWljdGFiKG1vZGVscywgbW9kbmFtZXM9bW9kbmFtZXMpDQoNCiMgQW5kIHRoZSBSMiB0aGluZy4NCnN1bW1hcnkoc3EueC5tYXR1cmUpJHIuc3F1YXJlZA0Kc3VtbWFyeShzcS54Lm9sZCkkci5zcXVhcmVkDQpzdW1tYXJ5KHNxLngub2xkZXIpJHIuc3F1YXJlZA0KYGBgDQoNCldoaWNoIGRvZXMgbm90IGxvb2sgcHJvbWlzaW5nLiBCdXQgdGhlIG90aGVyIG9wdGlvbiBpcyB0byBsb29rIGF0IGNvcmUgYXJlYSwgYXNzdW1pbmcgc3F1aXJyZWxzIGF2b2lkIGVkZ2UuIFRoZSBwcm9ibGVtIGhlcmUgaXMgdGhhdCBJIHNob3VsZCBjb21iaW5lIGJvdGggb2xkIGFuZCBtYXR1cmUgZm9yZXN0IGludG8gYSBzaW5nbGUgY2F0ZWdvcnksIHNvIHRoYXQgZWRnZSBiZXR3ZWVuIHRoZW0gZG9lc24ndCBjb3VudCwgYW5kIHRoYXQgcHJvYmFibHkgcmVxdWlyZXMgcmVtYWtpbmcgbXkgcmFzdGVyLg==